package com.khyr.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.khyr.dao.*;
import com.khyr.entity.*;
import com.khyr.feign.UserFeign;
import com.khyr.service.RegisteredService;
import com.khyr.utils.SnowflakeIdGenerator;
import com.khyr.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author ：Zhang
 * @date ：Created in 2025/3/13 17:07
 * @description：门诊挂号
 * @modified By：
 * @version:
 */
@Service
public class RegisteredServiceImpl implements RegisteredService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private DeptDao deptDao;
    @Autowired
    private SysRegisteredItemDao sysRegisteredItemDao;
    @Autowired
    private SchedulingDao schedulingDao;
    @Autowired
    private HisRegistrationDao hisRegistrationDao;
    @Autowired
    private HisPatientDao hisPatientDao;
    @Autowired
    private UserFeign userFeign;
    /**
     * @create by: Zr
     * @description: 查询可用的挂号项目信息
     * @create time: 2025/3/13 19:01
     * @param
     * @return com.khyr.vo.R<java.util.List<com.khyr.entity.SysRegisteredItem>>
     */
    @Override
    public R<List<SysRegisteredItem>> getAllRegisteredItem() {
        QueryWrapper<SysRegisteredItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", "0");
        queryWrapper.eq("status", "0");
        List<SysRegisteredItem> sysRegisteredItems = sysRegisteredItemDao.selectList(queryWrapper);
        if(sysRegisteredItems.size()>0){
            return new R<>(200,"查询成功",sysRegisteredItems);
        }else{
            return new R<>(500,"查询失败",null);
        }

    }
    /**
     * @create by: Zr
     * @description: 根据科室，时间，类型查询可挂号的信息
     * @create time: 2025/3/13 20:30
     * @param data
     * @return com.khyr.vo.R<java.util.List<com.khyr.vo.FindSchedulingListDto>>
     */
    @Override
    public R<List<FindSchedulingListDto>> findSchedulingList(FindSchedulingListVo data) {
        QueryWrapper<Scheduling> queryWrapper = new QueryWrapper<>();
        if(data.getDeptId()!=null){
            // 科室id
            queryWrapper.eq("dept_id",data.getDeptId());
        }
        if(data.getSchedulingType()!=null){
            // 挂号类型
            queryWrapper.eq("scheduling_type",data.getSchedulingType());
        }
        if(data.getSubsectionType()!=null){
            // 挂号时段
            queryWrapper.eq("subsection_type",data.getSubsectionType());
        }
        if(data.getSchedulingDay()!=null){
            String dateTime = data.getSchedulingDay();
            // 以 "T" 分割字符串
            String[] parts = dateTime.split("T");
            // 取分割后的第一部分
            String date = parts[0];
            queryWrapper.eq("scheduling_day",date);
        }
        List<Scheduling> schedulings = schedulingDao.selectList(queryWrapper);
        // 获取最大挂号单号
        Integer maxRegistrationNumber = max();
        // 封装数据
        List<FindSchedulingListDto> lists = new ArrayList<>();
        for(Scheduling scheduling:schedulings){
            QueryWrapper<Dept> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("dept_id",scheduling.getDeptId());
            String deptName = deptDao.selectOne(queryWrapper1).getDeptName();
            FindSchedulingListDto findSchedulingListDto =
                    new FindSchedulingListDto(Long.valueOf(scheduling.getDeptId()),deptName,Long.valueOf(maxRegistrationNumber+1));
            lists.add(findSchedulingListDto);
        }
        return new R<>(200,"查询成功",lists);
    }
    /**
     * @create by: Zr
     * @description: 用于挂号
     * @create time: 2025/3/14 11:24
     * @param data
     * @param tokenName
     * @return com.khyr.vo.R<java.lang.String>
     */
    @Override
    public R<String> addRegistration(FindSchedulingListAndPatientVo data, String tokenName) {
        // 获取接诊的医生信息
        QueryWrapper<Scheduling> queryWrapper = new QueryWrapper<>();
        if(data.getRegistrationDto().getDeptId()!=null){
            queryWrapper.eq("dept_id",data.getRegistrationDto().getDeptId());
        }
        if(data.getRegistrationDto().getVisitDate()!=null){
            queryWrapper.eq("scheduling_day",data.getRegistrationDto().getVisitDate());
        }
        if(data.getRegistrationDto().getSchedulingType()!=null){
            queryWrapper.eq("scheduling_type",data.getRegistrationDto().getSchedulingType());
        }
        if(data.getRegistrationDto().getSubsectionType()!=null){
            queryWrapper.eq("subsection_type",data.getRegistrationDto().getSubsectionType());
        }
        List<Scheduling> schedulings = schedulingDao.selectList(queryWrapper);

        // 根据符合要求的医生的数量获得随机选择医生
//        Integer size = schedulings.size();
//        Integer randomIndex = (int) (Math.random() * size);
//        Scheduling scheduling = schedulings.get(randomIndex);
//        Integer userId = scheduling.getUserId();
//        // 通过医生id获得医生信息
//        QueryWrapper<User> queryWrapperUser = new QueryWrapper<>();
//        queryWrapperUser.eq("user_id",userId);
//        User user = userDao.selectOne(queryWrapperUser);
//        // 将未存储的患者信息存储入表中
        String addPatientId = addPatient(data.getPatientDto());
        //将信息存入hisRegistration表中，默认为未付费状态,存储患者信息和挂号信息

        // 挂号流水号
        HisRegistration hisRegistration = new HisRegistration();
        String registration_id = "GH"+SnowflakeIdGenerator.nextId();
        hisRegistration.setRegistrationId(registration_id);
        // 存入患者id
        if("0".equals(addPatientId)){
            hisRegistration.setPatientId(data.getPatientDto().getPatientId());
        }else {
            hisRegistration.setPatientId(addPatientId);
        }
        // 存入患者姓名
        hisRegistration.setPatientName(data.getPatientDto().getName());
        // 存入接诊医生id
        // hisRegistration.setUserId(user.getUserId());
        // 存入医生姓名
        // hisRegistration.setDoctorName(user.getUserName());
        // 存入科室id
        hisRegistration.setDeptId(Long.valueOf(data.getRegistrationDto().getDeptId()));
        // 存入挂号费用id
        hisRegistration.setRegistrationItemId(Long.valueOf(data.getRegistrationDto().getRegItemId()));
        // 存入挂号费用
        hisRegistration.setRegistrationAmount(BigDecimal.valueOf(Long.valueOf(data.getRegistrationDto().getRegItemAmount())));
        // 存入挂号编号
        hisRegistration.setRegistrationNumber(max()+1);
        // 挂号状态,默认未付费
        hisRegistration.setRegistrationStatus("0");
        // 就诊日期
        hisRegistration.setVisitDate(data.getRegistrationDto().getVisitDate());
        // 排班类型
        hisRegistration.setSchedulingType(data.getRegistrationDto().getSchedulingType());
        // 排班时段
        hisRegistration.setSubsectionType(data.getRegistrationDto().getSubsectionType());
        // 创建时间
        hisRegistration.setCreateTime(new Date());
        // 更新时间
        hisRegistration.setUpdateTime(new Date());
        // 获得创建人姓名
        hisRegistration.setCreateBy(tokenName);
        // 插入数据
        int insert = hisRegistrationDao.insert(hisRegistration);
        if(insert>0){
            return new R<>(200,"挂号成功", registration_id);
        }else{
            return new R<>(500,"挂号失败", null);
        }
     }
    /**
     * @create by: Zr
     * @description: 根据挂号单号将挂号单状态改为已挂号,用于收费
     * @create time: 2025/3/14 11:30
     * @param registrationId
     * @return com.khyr.vo.R<java.lang.String>
     */
    @Override
    public R<String> collectFee(String registrationId) {
        // 根据挂号单号将挂号单状态改为已挂号
        HisRegistration hisRegistration = hisRegistrationDao.selectById(registrationId);
        hisRegistration.setRegistrationStatus("1");
        hisRegistrationDao.updateById(hisRegistration);
        return new R<>(200,"收费成功",null);
    }
    /**
     * @create by: Zr
     * @description: 用于添加手机端的挂号信息，并判断预约的时间是否合法
     * @create time: 2025/3/18 20:17
     * @param data
     * @param patientId
     * @param name
     * @return com.khyr.vo.R<java.lang.String>
     */
    @Override
    public R<String> addAppRegistration(addAppRegistrationVo data, String patientId,String name) {
        // 获取当前时间，如果现在时间小于上午8点，则最多可以挂今天上午的号，如果时间小于中午12点，则最多能挂今天下午的号，如果时间小于下午5点，则最多可以挂今天晚上的号
        // subsectionType为1是上午，2是下午，3是晚上，visitDate是日期
        // 当前时间
        String now = DateUtil.today();
        // 用户的挂号日期
        String date = data.getVisitDate().split("\\(")[0];
        // 时间格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate now1 = LocalDate.parse(now, formatter);
        LocalDate date1 = LocalDate.parse(date, formatter);
        // 判断时间，如果用户挂号日期小于当前日期，则提示用户不能挂过时号
        if (now1.isBefore(date1)) {
            // 当前时间<用户预约的挂号时间
        }else if(now1.isAfter(date1)){
            return new R<>(500,"不能挂过时号",null);
        }else if(now1.isEqual(date1)){
            if("1".equals(data.getSubsectionType())){
                // 如果用户选择的是上午，则判断当前时间是否大于8点，如果大于8点，则提示用户不能挂过时号
                if(DateUtil.hour(new Date(),true)>8){
                    return new R<>(500,"不能挂过时号",null);
                }
            }else if("2".equals(data.getSubsectionType())){
                // 如果用户选择的是下午，则判断当前时间是否大于12点，如果大于12点，则提示用户不能挂过时号
                if(DateUtil.hour(new Date(),true)>12) {
                    return new R<>(500, "不能挂过时号", null);
                }
            }
            if("3".equals(data.getSubsectionType())){
                // 如果用户选择的是晚上，则判断当前时间是否大于17点，如果大于17点，则提示用户不能挂过时号
                if(DateUtil.hour(new Date(),true)>17) {
                    return new R<>(500, "不能挂过时号", null);
                }
            }
        }
        // 挂号流水号
        HisRegistration hisRegistration = new HisRegistration();
        String registration_id = "GH"+SnowflakeIdGenerator.nextId();
        hisRegistration.setRegistrationId(registration_id);
        // 存入患者id
        hisRegistration.setPatientId(patientId);
        // 存入患者姓名
        hisRegistration.setPatientName(name);
        // 存入医生id
        hisRegistration.setUserId(data.getUser().getUserId());
        // 存入医生姓名
        hisRegistration.setDoctorName(data.getUser().getUserName());
        // 存入科室id
        hisRegistration.setDeptId(Long.valueOf(data.getDeptId()));
        //  挂号费用id,默认为门诊挂号
        hisRegistration.setRegistrationItemId(1L);
        // 挂号费用
        hisRegistration.setRegistrationAmount(BigDecimal.valueOf(6));
        // 存入挂号编号
        hisRegistration.setRegistrationNumber(max()+1);
        // 挂号状态,默认未付费
        hisRegistration.setRegistrationStatus("0");
        // 就诊日期
        hisRegistration.setVisitDate(data.getVisitDate().split("\\(")[0]);
        // 排班类型,默认为门诊
        hisRegistration.setSchedulingType("1");
        // 排班时段
        hisRegistration.setSubsectionType(data.getSubsectionType());
        // 创建时间
        hisRegistration.setCreateTime(new Date());
        // 更新时间
        hisRegistration.setUpdateTime(new Date());
        // 获得创建人姓名
        hisRegistration.setCreateBy("患者："+name);
        // 插入数据
        int insert = hisRegistrationDao.insert(hisRegistration);
        if(insert>0){
            return new R<>(200,"挂号成功", registration_id);
        }else{
            return new R<>(500,"挂号失败", null);
        }
    }

    /**
     * @create by: Zr
     * @description: 判断患者是否存在，若不存在则添加患者信息，若存在则返回患者id
     * @create time: 2025/3/14 11:29
     * @param patientVo
     * @return java.lang.String
     */
    private String addPatient(PatientDto patientVo){
        if(patientVo.getPatientId() == null){
            // 患者id
            String patient_id = "HZ"+SnowflakeIdGenerator.nextId();
            HisPatient hisPatient = new HisPatient();
            if(patientVo.getName() != null){
                // 姓名
                hisPatient.setName(patientVo.getName());
            }
            if(patientVo.getPhone() != null){
                // 手机号
                hisPatient.setPhone(patientVo.getPhone());
            }
            if(patientVo.getSex() != null){
                // 性别
                hisPatient.setSex(patientVo.getSex());
            }
            if(patientVo.getAddress() != null){
                // 地址
                hisPatient.setAddress(patientVo.getAddress());
            }
            if(patientVo.getIdCard() != null){
                // 身份证号
                hisPatient.setIdCard(patientVo.getIdCard());
            }
            if(patientVo.getIsFinal() != null){
                //
                hisPatient.setIsFinal("0");
            }
            if(patientVo.getBirthday() != null){
                hisPatient.setBirthday(patientVo.getBirthday());
            }
            if(patientVo.getPassword() != null){
                hisPatient.setPassword("$10$cI7e7bgSs9.9nNHhxKO9LuK/Ll.AeZwgUyZb77oD2y3UwwZyZhWG6");
            }
            hisPatient.setCreateTime(new Date());
            hisPatient.setUpdateTime(new Date());
            hisPatient.setPatientId(patient_id);
            int insert = hisPatientDao.insert(hisPatient);
            if(insert>0){
                return patient_id;
            }else{
                return "0";
            }
        }
        return "0";
    }
    /**
     * @create by: Zr
     * @description: 获取最大挂号单号
     * @create time: 2025/3/14 11:30
     * @param
     * @return java.lang.Integer
     */
    private Integer max(){
        // 获取最大挂号单号
        Integer maxRegistrationNumber = 0;
        QueryWrapper<HisRegistration> queryWrapper2 = new QueryWrapper<>();
        List<HisRegistration> hisRegistrations = hisRegistrationDao.selectList(queryWrapper2);
        for(HisRegistration hisRegistration:hisRegistrations){
            Integer registrationNumber = hisRegistration.getRegistrationNumber();
            if(registrationNumber>maxRegistrationNumber){
                maxRegistrationNumber = registrationNumber;
            }
        }
        return maxRegistrationNumber;
    }

}
